package buildcode;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import org.apache.commons.lang3.ArrayUtils;
import org.junit.jupiter.api.Test;

import buildcode.build.BuildCommand;
import buildcode.build.BuildCommandBuilder;
import buildcode.database.DataBaseTable;
import buildcode.language.java.type.JavaType;
import buildcode.shop.VueEntityCommandExecute;
import buildcode.shop.VueListPageCommandExecute;
import buildcode.support.ContextIdConstant;
import buildcode.support.SmartBuildCommndBuilder;
import buildcode.util.CommonUtil;
import buildcode.util.DataBaseUtil;

public class ShopBuild {

    @Test
    public void user() {
        build("user", "system", new String[] {}, new String[] {}, new String[] {});
    }

    @Test
    public void warehouse() {
        build("product", "warehouse", new String[] {}, new String[] {}, new String[] {});
    }

    @Test
    public void product() {
        build("product", "product", new String[] { "shop_service" }, new String[] { "shop_goods_service" }, new String[] { "shop_service" });
    }

    public void build(String projectName, String module, String[] all, String[] daoOnly, String[] front) {

        List<DataBaseTable> res = DataBaseUtil.getTableInfo("jdbc:mysql://localhost/feature_shop?useUnicode=true&characterEncoding=UTF-8&useSSL=false", "root", "123456abc",
                Stream.of(all, daoOnly, front).flatMap(Arrays::stream).toArray(String[]::new));
        String xmlMapperSrc = "D:\\git\\spring-cloud-shop\\feature-shop-" + projectName + "\\feature-shop-" + projectName + "-service\\src\\main\\resources";
        String apiSrc = "D:\\git\\spring-cloud-shop\\feature-shop-" + projectName + "\\feature-shop-" + projectName + "-api\\src\\main\\java";
        String javaSrc = "D:\\git\\spring-cloud-shop\\feature-shop-" + projectName + "\\feature-shop-" + projectName + "-service\\src\\main\\java";
        String tplDir = "shop";
        Context.setServletContextPath(projectName);
        String javaPackage = "com.feature.shop." + projectName;
        String apiPackage = "com.feature.shop." + projectName + ".api";
        Context.setApplicationName("ApiNameConstant.APPLICATION_NAME");
        Context.setTablePrfix("shop");
        Context.setAuthor("wangzhiyue");
        // 前端
        String frontTplDir = "shop/vue";
        String frontSrc = "D:\\vscode_git\\feature-shop-admin\\src";
        Context.put("module", module);
        for (DataBaseTable base : res) {
            if (ArrayUtils.contains(all, base.getTableName())) {
                BuildCommand entity = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_ENTITY, tplDir).setPackageName(javaPackage + ".model.entity").setSrcLocation(javaSrc).build();
                BuildCommand vo = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_VO, tplDir).setPackageName(apiPackage + ".vo").setSrcLocation(apiSrc).build();
                BuildCommand enumEntity = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_ENUM, tplDir).setPackageName(apiPackage + ".enums").setSrcLocation(apiSrc).build();
                BuildCommand listRequest = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_LISTREQUEST, tplDir).setPackageName(apiPackage + ".request").setSrcLocation(apiSrc)
                        .setRequestTimeField(new String[] { "createTime" }).build();
                BuildCommand pageRequest = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_PAGEREQUEST, tplDir).setPackageName(apiPackage + ".request").setSrcLocation(apiSrc)
                        .setRequestTimeField(new String[] { "createTime" }).build();
                BuildCommand addRequest = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_ADDREQUEST, tplDir).setPackageName(apiPackage + ".request").setSrcLocation(apiSrc)
                        .setExcludeField(new String[] { "createTime", "createUser", "updateTime", "updateUser", "id" }).build();
                BuildCommand updateRequest = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_UPDATEREQUEST, tplDir).setPackageName(apiPackage + ".request").setSrcLocation(apiSrc)
                        .setExcludeField(new String[] { "createTime", "createUser", "updateTime", "updateUser" }).build();
                BuildCommand delRequest = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_DELREQUEST, tplDir).setPackageName(apiPackage + ".request").setSrcLocation(apiSrc)
                        .setIncludeField(new String[] { "id" }).build();
                BuildCommand query = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_QUERY, tplDir).setPackageName(javaPackage + ".model.query").setSrcLocation(javaSrc)
                        .setRequestTimeField(new String[] { "createTime" }).build();
                BuildCommand javaMapper = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_JAVA_MAPPER, tplDir).setPackageName(javaPackage + ".mapper").setSrcLocation(javaSrc).build();
                BuildCommand xmlMapper = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_XML_MAPPER, tplDir).setPackageName("mapper").setSrcLocation(xmlMapperSrc)
                        .setRequestTimeField(new String[] { "createTime" }).setExportFileType("xml").build();
                BuildCommand converter = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_CONVERTER, tplDir).setPackageName(javaPackage + ".converter").setSrcLocation(javaSrc).build();
                BuildCommand service = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_SERVICE, tplDir).setPackageName(javaPackage + ".service").setSrcLocation(javaSrc).build();
                BuildCommand feignApi = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_FEIGN_API, tplDir).setPackageName(apiPackage).setSrcLocation(apiSrc)
                        .setImportTypes(Arrays.asList(new JavaType("ApiNameConstant", apiPackage + ".constants"))).build();
                BuildCommand controller = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_FEIGN_CONTROLLER, tplDir).setPackageName(javaPackage + ".controller").setSrcLocation(javaSrc).build();
                entity.setNext(vo).setNext(enumEntity).setNext(listRequest).setNext(pageRequest).setNext(addRequest).setNext(updateRequest).setNext(delRequest).setNext(query).setNext(javaMapper)
                        .setNext(xmlMapper).setNext(converter).setNext(service).setNext(feignApi).setNext(controller);
                entity.execute(base);
            }
            if (ArrayUtils.contains(daoOnly, base.getTableName())) {
                BuildCommand entity = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_ENTITY, tplDir).setPackageName(javaPackage + ".model.entity").setSrcLocation(javaSrc).build();
                BuildCommand vo = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_VO, tplDir).setPackageName(apiPackage + ".vo").setSrcLocation(apiSrc).build();
                BuildCommand enumEntity = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_ENUM, tplDir).setPackageName(apiPackage + ".enums").setSrcLocation(javaSrc).build();
                BuildCommand javaMapper = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_JAVA_MAPPER, tplDir).setPackageName(javaPackage + ".mapper").setSrcLocation(javaSrc).build();
                BuildCommand xmlMapper = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_XML_MAPPER, tplDir).setPackageName("mapper").setSrcLocation(xmlMapperSrc)
                        .setRequestTimeField(new String[] { "createTime" }).setExportFileType("xml").build();
                entity.setNext(vo).setNext(enumEntity).setNext(javaMapper).setNext(xmlMapper);
                entity.execute(base);
            }
            if (ArrayUtils.contains(front, base.getTableName())) {
                String entityName = base.getCamelCaseName();
                if (base.getTableName().startsWith(Context.getTablePrfix())) {
                    entityName = entityName.replace(CommonUtil.firstUpper(Context.getTablePrfix()), "");
                }
                String lname = entityName.toLowerCase();
                BuildCommand ApiPage = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_FORNT_API_PAGE, frontTplDir).setPackageName("api\\" + module).setSrcLocation(frontSrc)
                        .setExportFileType("ts").setFileName(lname + "Api").setTpl(frontTplDir + "/ApiPage.vm").setExecute(null).build();
                BuildCommand listPage = BuildCommandBuilder.of(ContextIdConstant.CONTEXT_ID_FORNT_LIST_PAGE, frontTplDir + "/ListPage.vm").setPackageName("views\\" + module + "\\" + lname)
                        .setSrcLocation(frontSrc).setExportFileType("vue").setFileName("index")
                        .setExecute(new VueListPageCommandExecute(new String[] { "createUser", "updateUser", "updateTime", "id" }, new String[] { "createUser", "updateUser", "id" })).build();
                BuildCommand addPage = BuildCommandBuilder.of(ContextIdConstant.CONTEXT_ID_FORNT_ADD_PAGE, frontTplDir + "/AddPage.vm").setPackageName("views\\" + module + "\\" + lname)
                        .setSrcLocation(frontSrc).setExportFileType("vue").setExcludeField(new String[] { "createTime", "createUser", "updateTime", "updateUser", "id" })
                        .setFileName(entityName + "Add").setExecute(new VueEntityCommandExecute()).build();
                BuildCommand updatePage = BuildCommandBuilder.of(ContextIdConstant.CONTEXT_ID_FORNT_UPDATE_PAGE, frontTplDir + "/UpdatePage.vm").setPackageName("views\\" + module + "\\" + lname)
                        .setSrcLocation(frontSrc).setExportFileType("vue").setExcludeField(new String[] { "createTime", "createUser", "updateTime", "updateUser", "id" })
                        .setExecute(new VueEntityCommandExecute()).setFileName(entityName + "Update").build();
                BuildCommand typePage = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_FORNT_TYPE_PAGE, frontTplDir).setPackageName(module)
                        .setSrcLocation("D:\\vscode_git\\feature-shop-admin\\types").setExportFileType("d.ts").setFileName(lname).build();
                ApiPage.setNext(listPage).setNext(addPage).setNext(updatePage).setNext(typePage);
                ApiPage.execute(base);
            }
        }
        if (front.length > 0) {
            BuildCommand enumPage = SmartBuildCommndBuilder.of(ContextIdConstant.CONTEXT_ID_FORNT_ENUM_PAGE, frontTplDir).setPackageName("enums").setSrcLocation(frontSrc).setExportFileType("ts")
                    .setFileName(module + "Enum").build();
            enumPage.execute(res);
        }
    }

}
